package com.exmple.myapplication;

import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;

import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import jxl.read.biff.BiffException;
import jxl.write.WritableCellFormat;
import jxl.write.WriteException;
import me.zhouzhuo.zzexcelcreator.ZzExcelCreator;
import me.zhouzhuo.zzexcelcreator.ZzFormatCreator;

/**
 * @author 27229
 */
public class ExcelUtil {
    private static ExcelUtil instance;

    private  String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "excel" + File.separator;

    public ExcelUtil setPath(String path) {
        if (!path.endsWith(File.separator)) {
            this.path = path+File.separator;
        }
        return instance;
    }

    private final ScheduledExecutorService scheduledExecutorService;
    private final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA);
//    private final Queue<Collection<String>> queueMsg = new ConcurrentLinkedQueue<>();

    private int row;
    private int col;
    /* private final Runnable runnable = new Runnable() {
         @Override
         public void run() {
             Collection<String> poll = queueMsg.poll();
             if (poll != null) {
                 for (String s : poll
                 ) {
                     addString(s);
                     col++;
                 }
                 row++;
                 col = 0;
             }
         }
     };*/
    private String fileName;
    private ScheduledFuture<?> scheduledFuture;

    public static ExcelUtil getInstance() {
        if (instance == null) {
            instance = new ExcelUtil();
        }
        return instance;
    }


    public void putFloatData(Collection<Float> collection) {
        int row = this.row;
        this.row++;
        int col = 0;
        for (Float f:collection
             ) {
            addNum(row,col,f);
            col++;
        }
    }

    public void putStringData(Collection<String> collection) {
       int row = this.row;
       this.row++;
       int col = 0;
        for (String f:collection
        ) {
            addString(row,col,f);
            col++;
        }
    }

    private void addString(int row, int col, String str) {

        ZzExcelCreator zzExcelCreator;
        try {
            zzExcelCreator = ZzExcelCreator
                    .getInstance()
                    .openExcel(new File(path + fileName + ".xls"))
                    .openSheet(0);
            WritableCellFormat cellFormat = ZzFormatCreator
                    .getInstance()
//                    .setAlignment(Alignment.CENTRE, VerticalAlignment.CENTRE)
//                    .setFontSize(14)
                    .getCellFormat();
            zzExcelCreator
                    .fillContent(col, row, str, cellFormat)
                    .close();
        } catch (IOException | BiffException | WriteException e) {
            e.printStackTrace();
            Log.e(getClass().getSimpleName(), e.toString());
        }

    }

    private void addNum(int row, int col, Float str) {
        ZzExcelCreator zzExcelCreator;
        try {
            zzExcelCreator = ZzExcelCreator
                    .getInstance()
                    .openExcel(new File(path + fileName + ".xls"))
                    .openSheet(0);
            WritableCellFormat cellFormat = ZzFormatCreator
                    .getInstance()
//                    .setAlignment(Alignment.CENTRE, VerticalAlignment.CENTRE)
//                    .setFontSize(14)
                    .getCellFormat();
            zzExcelCreator
                    .fillNumber(col, row, str, cellFormat)
                    .close();
        } catch (IOException | BiffException | WriteException e) {
            e.printStackTrace();
            Log.e(getClass().getSimpleName(), e.toString());
        }

    }

    public void createExcel(String fileName,Collection<String> titles, ExcelListener listener) {
        if (TextUtils.isEmpty(fileName)) {
            this. fileName = simpleDateFormat.format(new Date(System.currentTimeMillis()));
        } else {
            this.fileName =fileName;
        }
        String finalFileName = this. fileName;
        Observable.create((ObservableOnSubscribe<Boolean>) emitter -> {
                    try {
                        ZzExcelCreator.getInstance().createExcel(path, finalFileName).createSheet("1").close();
                        row = 0;
                        col = 0;
                        for (String s : titles
                        ) {
                            addString(row, col, s);
                            col++;
                        }
                        row++;
                        col = 0;
//                        scheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(runnable, 50, 50, TimeUnit.MILLISECONDS);
                        emitter.onNext(true);
                    } catch (IOException | WriteException e) {
                        e.printStackTrace();
                        emitter.onNext(false);
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Boolean>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Boolean aBoolean) {
                        if (listener != null) {
                            listener.onCreateOpenCallback(aBoolean);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    /*
    * */
    public boolean finish() {
        if (scheduledFuture != null) {
            scheduledFuture.cancel(false);
        }
        scheduledExecutorService.shutdown();
        instance = null;
        return true;
    }

    private ExcelUtil() {
        ThreadFactory threadFactory = r -> new Thread(r, "excel");
        scheduledExecutorService = new ScheduledThreadPoolExecutor(2, threadFactory);
    }

    public interface ExcelListener {
        /*
         * 创建文件时回调，成功或者失败，失败时检查权限，成功方可写入数据
         * */
        void onCreateOpenCallback(boolean isReady);
    }
}
